module uart_receiver (
    input wire clk_in,           // 50MHz时钟
    // input wire rst_n,           // 复位信号低有效
    input wire sin,           // 串行输入
    output reg [7:0] sdata  = 8'd0,      // 接收到的8位数据
    output reg data_valid   = 1'b0,       // 数据有效标志 上升沿有效
    output reg parity_valid = 1'b0      // 奇校验结果（1=正确）
);

// 参数定义
parameter clk_in_FREQ = 50_000_000;  // 50MHz
parameter BAUD_RATE = 115200;     // 波特率
parameter SAMPLE_COUNT = clk_in_FREQ / BAUD_RATE;  // 每个位周期的时钟数

// 状态定义
parameter IDLE      = 3'b000;
parameter START_BIT = 3'b001;
parameter DATA_BITS = 3'b010;
parameter PARITY_BIT = 3'b011;
parameter STOP_BIT  = 3'b100;

// 内部寄存器
reg [2:0] current_state = IDLE;
reg [2:0] next_state = IDLE;
reg [15:0] baud_counter = 16'd0;
reg [3:0] bit_counter = 4'd0;
reg [7:0] shift_reg_sdata = 8'd0;
reg parity_calc  = 1'b0;

// 8位移位寄存器
reg [6:0] shift_reg_sin = 7'd0;
wire sin_start;          // 检测起始位
wire sin_sample_data;    // 检测数据位

// 采样点信号
wire sample_point = (baud_counter == (SAMPLE_COUNT/2));
wire bit_end = (baud_counter == SAMPLE_COUNT - 1);

// 将外部sin同步进入模块
always @(posedge clk_in) begin
    shift_reg_sin <= {shift_reg_sin[6:0], sin};
end


assign sin_start = (shift_reg_sin == 7'b1111000);
assign sin_sample_data = ((shift_reg_sin[2] & shift_reg_sin[3]) 
                        | (shift_reg_sin[2] & shift_reg_sin[4]) 
                        | (shift_reg_sin[3] & shift_reg_sin[4])) ;


// ==================== 第一段：状态寄存器 ====================
always @(posedge clk_in) begin
    current_state <= next_state;    
    // 波特率计数器
    if (current_state != IDLE) begin
        if (bit_end) begin
            baud_counter <= 0;
        end else begin
            baud_counter <= baud_counter + 1;
        end
    end else begin
        baud_counter <= 0;
    end
    
    // 数据位计数器
    if (current_state == DATA_BITS && (bit_end == 1'b1)) begin
        if (bit_counter == 4'd8) begin
            bit_counter <= 0;
        end else begin
            bit_counter <= bit_counter + 1;
        end
    end else if (current_state == IDLE) begin
        bit_counter <= 0;
    end
end


// ==================== 第二段：下一状态逻辑 ====================
always @(*) begin
    case (current_state)
        IDLE: begin
            if (sin_start == 1'b1) begin  // 检测起始位（下降沿）
                next_state = START_BIT;
            end else begin
                next_state = IDLE;
            end
        end
        
        START_BIT: begin
            if (sample_point) begin
                if (sin_sample_data == 1'b0) begin  // 确认起始位有效
                    next_state = DATA_BITS;
                end else begin
                    next_state = IDLE;  // 假起始位
                end
            end else begin
                next_state = START_BIT;
            end
        end
        
        DATA_BITS: begin
            // if ((bit_end == 1'b1) && (bit_counter == 3'd7)) begin
            if ((bit_end == 1'b1) && (bit_counter == 4'd8)) begin
                next_state = PARITY_BIT;
            end else begin
                next_state = DATA_BITS;
            end
        end
        
        PARITY_BIT: begin
            if (bit_end) begin
                next_state = STOP_BIT;
            end else begin
                next_state = PARITY_BIT;
            end
        end
        
        STOP_BIT: begin
            if (sample_point) begin
                next_state = IDLE;
            end else begin
                next_state = STOP_BIT;
            end
        end
        
        default: begin
            next_state = IDLE;
        end
    endcase
end

// ==================== 第三段：输出逻辑 ====================
always @(posedge clk_in) begin
    case (current_state)    // 仅奇偶校验和接收完成阶段输出
        IDLE: begin
            parity_calc <= 1'b0;
        end

        START_BIT: begin
            data_valid <= 1'b0;
            parity_valid <= 1'b0;
            shift_reg_sdata <= 8'b0;
        end

        DATA_BITS: begin  // 数据位采样 校验和计算
            if (sample_point) begin
                shift_reg_sdata[bit_counter - 1] <= sin_sample_data;
                parity_calc <= parity_calc ^ sin_sample_data;
            end
        end


        PARITY_BIT: begin
            if (sample_point) begin
                // 奇校验验证：数据+校验位中1的总数应为奇数
                parity_valid <= ((parity_calc ^ sin_sample_data) == 1'b1);
            end
        end
        
        STOP_BIT: begin
            if (sample_point) begin
                if (sin_sample_data == 1'b1) begin  // 验证停止位
                    sdata <= shift_reg_sdata;    // 输出接收到的数据
                    data_valid <= 1'b1;    // 数据有效
                end
            end
        end
        
        default: begin
            // 输出复位值
            sdata <= 8'h00;
            data_valid <= 1'b0;
            parity_valid <= 1'b0;
        end
    endcase
end


endmodule
